package com.avalon.shop.controller;

import com.avalon.core.model.RecordRow;
import com.avalon.core.util.JacksonUtil;
import com.avalon.core.util.ObjectUtils;
import com.avalon.shop.model.MediaCheckAsyncResponse;
import com.avalon.shop.model.WXCode2Session;
import com.avalon.shop.model.WxUserPhoneInfo;
import com.avalon.shop.model.WxaMediaCheckMsg;
import com.avalon.shop.service.UserService;
import com.avalon.shop.service.WxCheckRecordService;
import com.avalon.shop.service.wx.WeiXinShopService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.net.http.HttpResponse;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import java.util.*;

@RestController
@RequestMapping("/wx")
@Slf4j
public class WxShopController {
    private final WeiXinShopService weiXinShopService;
    private UserService userService;
    private WxCheckRecordService wxCheckRecordService;

    public WxShopController(WeiXinShopService weiXinShopService,
                            UserService userService,
                            WxCheckRecordService wxCheckRecordService) {
        this.weiXinShopService = weiXinShopService;
        this.userService = userService;
        this.wxCheckRecordService = wxCheckRecordService;
    }


    @GetMapping("/auth/code2Session/{code}")
    public Map getOpenId(@PathVariable("code") String code) {
        WXCode2Session openId = weiXinShopService.getOpenId(code);
        if (ObjectUtils.isNull(openId.getErrcode()) || openId.getErrcode() == 0) { // 成功获取
            openId.setUserId(userService.getOrCreatePetUser(openId.getOpenid()));
        }
        Map map = new HashMap<String, Object>();
        map.put("openid", openId.getOpenid());
        map.put("userId", openId.getUserId());
        return map;
    }

    @GetMapping("/auth/phone/{userId}/{code}")
    public RecordRow getUserPhone(@PathVariable("code") String code, @PathVariable("userId") Integer userId) {
        WxUserPhoneInfo wxUserPhoneInfo = weiXinShopService.getUserPhone(code);
        userService.updateUserPhone(userId, wxUserPhoneInfo.getPurePhoneNumber(), wxUserPhoneInfo.getCountryCode());
        return RecordRow.build().put("phone", wxUserPhoneInfo.getPhoneNumber());
    }

    @PostMapping("/get/qrcode")
    public byte[] getUnlimitedQRCode(@RequestBody Map<String, Object> param) {
        String scene = "";
        String page = "";
        if (param.containsKey("scene")) {
            scene = param.get("scene").toString();
        }
        if (param.containsKey("page")) {
            page = param.get("page").toString();
        }
        return weiXinShopService.getWXACodeUnlimited(scene, page);
    }

    @PostMapping("/check/text/user/info")
    public Map check_text_user_info(@RequestBody Map<String, Object> param) {
        String openId = null;
        if (param.containsKey("openId")) {
            openId = param.get("openId").toString();
        }
        String content = null;
        if (param.containsKey("content")) {
            content = param.get("content").toString();
        }
        Map<String, Object> map = new HashMap<>();
        if (ObjectUtils.isNull(openId)) {
            map.put("code", 1);
            map.put("msg", "未登录,请先登录");
            return map;
        }
        if (ObjectUtils.isNull(content)) {
            map.put("code", 0);
            return map;
        }
        Boolean b = weiXinShopService.check_text_user_info(openId, content);
        map.put("code", 1);
        if (b) {
            map.put("code", 0);
        } else {
            map.put("msg", "信息含违规信息");
        }
        return map;
    }

    @PostMapping("/check/text/user/comment")
    public Map check_text_user_comment(@RequestBody Map<String, Object> param) {
        String openId = null;
        if (param.containsKey("openId")) {
            openId = param.get("openId").toString();
        }
        String content = null;
        if (param.containsKey("content")) {
            content = param.get("content").toString();
        }
        Map<String, Object> map = new HashMap<>();
        if (ObjectUtils.isNull(openId)) {
            map.put("code", 1);
            map.put("msg", "未登录,请先登录");
            return map;
        }
        if (ObjectUtils.isNull(content)) {
            map.put("code", 0);
            return map;
        }
        Boolean b = weiXinShopService.check_text_user_comment(openId, content);
        map.put("code", 1);
        if (b) {
            map.put("code", 0);
        } else {
            map.put("msg", "信息含违规信息");
        }
        return map;
    }

    @PostMapping("/check/text/forum")
    public Map check_text_forum(@RequestBody Map<String, Object> param) {
        String openId = null;
        if (param.containsKey("openId")) {
            openId = param.get("openId").toString();
        }
        String content = null;
        if (param.containsKey("content")) {
            content = param.get("content").toString();
        }
        Map<String, Object> map = new HashMap<>();
        if (ObjectUtils.isNull(openId)) {
            map.put("code", 1);
            map.put("msg", "未登录,请先登录");
            return map;
        }
        if (ObjectUtils.isNull(content)) {
            map.put("code", 0);
            return map;
        }
        Boolean b = weiXinShopService.check_text_forum(openId, content);
        map.put("code", 1);
        if (b) {
            map.put("code", 0);
        } else {
            map.put("msg", "信息含违规信息");
        }
        return map;
    }

    @PostMapping("/check/image/user/info")
    public MediaCheckAsyncResponse check_image_user_info(@RequestBody Map<String, Object> param) {
        String openId = null;
        if (param.containsKey("openId")) {
            openId = param.get("openId").toString();
        }
        String image_url = null;
        if (param.containsKey("image_url")) {
            image_url = param.get("image_url").toString();
        }

        MediaCheckAsyncResponse response1 = MediaCheckAsyncResponse.BuildError();
        if (ObjectUtils.isNull(openId)) {
            response1.setErrmsg("未登录,请先登录");
            return response1;
        }
        if (ObjectUtils.isNull(image_url)) {
            response1.setErrcode(0);
            return response1;
        }
        return weiXinShopService.check_image_user_info(openId, image_url);
    }


    @PostMapping("/check/image/user/comment")
    public MediaCheckAsyncResponse check_image_user_comment(@RequestBody Map<String, Object> param) {
        String openId = null;
        if (param.containsKey("openId")) {
            openId = param.get("openId").toString();
        }
        String image_url = null;
        if (param.containsKey("image_url")) {
            image_url = param.get("image_url").toString();
        }

        MediaCheckAsyncResponse response1 = MediaCheckAsyncResponse.BuildError();
        if (ObjectUtils.isNull(openId)) {
            response1.setErrmsg("未登录,请先登录");
            return response1;
        }
        if (ObjectUtils.isNull(image_url)) {
            response1.setErrcode(0);
            return response1;
        }
        return weiXinShopService.check_image_user_comment(openId, image_url);
    }

    @PostMapping("/check/image/forum")
    public MediaCheckAsyncResponse check_image_forum(@RequestBody Map<String, Object> param) {
        String openId = null;
        if (param.containsKey("openId")) {
            openId = param.get("openId").toString();
        }
        String image_url = null;
        if (param.containsKey("image_url")) {
            image_url = param.get("image_url").toString();
        }
        MediaCheckAsyncResponse response1 = MediaCheckAsyncResponse.BuildError();
        if (ObjectUtils.isNull(openId)) {
            response1.setErrmsg("未登录,请先登录");
            return response1;
        }
        if (ObjectUtils.isNull(image_url)) {
            response1.setErrcode(0);
            return response1;
        }
        return weiXinShopService.check_image_forum(openId, image_url);
    }

    @GetMapping(value = "/check/image/push", produces = "text/plain;charset=utf-8")
    public String check_image_push_validate(@RequestParam("signature") String signature,
                                            @RequestParam("timestamp") String timestamp,
                                            @RequestParam("nonce") String nonce,
                                            @RequestParam("echostr") String echostr) {
        if (log.isDebugEnabled()) {
            log.debug("check_image_push_validate 参数 signature->{},timestamp->{},nonce->{},echostr->{}",
                    signature, timestamp, nonce, echostr);
        }
        List<String> list = new ArrayList<>();
        list.add(Token);// Token
        list.add(timestamp);// timestamp
        list.add(nonce);// nonce
        Collections.sort(list);
        String result = String.join("", list);
        result = calculateSHA1(result);
        Map<String, String> res = new HashMap();
        if (signature.equals(result)) {
            return echostr;
        }

        return "";
    }

    public String calculateSHA1(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            byte[] messageDigest = md.digest(input.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : messageDigest) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    private final String Token = "955980";

    @PostMapping("/check/image/push")
    public String check_image_push_handler(@RequestParam("signature") String signature,
                                           @RequestParam("timestamp") String timestamp,
                                           @RequestParam("nonce") String nonce,
                                           @RequestBody WxaMediaCheckMsg pushMsg) {
        if (log.isDebugEnabled()) {
            log.debug("check_image_push_handler 参数 signature->{},timestamp->{},nonce->{},pushMsg->{}",
                    signature, timestamp, nonce, JacksonUtil.object2String(pushMsg));
        }
        List<String> list = new ArrayList<>();
        list.add(Token);// Token
        list.add(timestamp);// timestamp
        list.add(nonce);// nonce
        Collections.sort(list);
        String result = String.join("", list);
        result = calculateSHA1(result);

        if (result.equals(signature)) {
            if (ObjectUtils.isNotNull(pushMsg.getResult())) {
                wxCheckRecordService.updateShareCheckRecord(pushMsg.getTrace_id(), pushMsg.getResult());
            }
        }

        return "success";
    }
}
